package middleware

import (
	"encoding/gob"
	"github.com/gin-contrib/sessions"
	"github.com/gin-gonic/gin"
	"net/http"
	"time"
)

type LoginMiddlewareBuilder struct {
	paths []string
}

func NewLoginMiddlewareBuilder() *LoginMiddlewareBuilder {
	return &LoginMiddlewareBuilder{}
}

// IgnorePaths 设置需要忽略登录校验的路径
// path: 需要忽略登录校验的路径
// 返回值: *LoginMiddlewareBuilder - 返回中间件构建器自身，支持链式调用
func (l *LoginMiddlewareBuilder) IgnorePaths(path string) *LoginMiddlewareBuilder {
	l.paths = append(l.paths, path)
	return l
}

// Build 构建登录中间件处理函数
// context: Gin框架的上下文对象
// 返回值: gin.HandlerFunc - Gin框架的处理函数，用于拦截未登录用户的请求
func (l *LoginMiddlewareBuilder) Build() gin.HandlerFunc {
	gob.Register(time.Now())
	return func(context *gin.Context) {
		// 允许访问登录和注册页面，无需登录检查

		for _, path := range l.paths {
			if context.Request.URL.Path == path {
				return
			}
		}

		// 获取当前会话信息
		sess := sessions.Default(context)
		if sess == nil {
			// 没有登录
			context.AbortWithStatus(http.StatusUnauthorized)
			return
		}
		userId := sess.Get("userId")

		if userId == nil {
			context.AbortWithStatus(http.StatusUnauthorized)
			return
		}
		sess.Set("userId", userId)
		// 设置user_id 以便到上下文
		context.Set("userId", userId)
		// 先拿到上一次的更新时间
		lastUpdateTime := sess.Get("update_time")
		// 说明还没有刷新过，刚登陆，还没刷新过
		now := time.Now()
		if lastUpdateTime == nil {
			sess.Set("update_time", now)
			_ = sess.Save()
			return
		}
		// 如果有更新时间，判断是否大于还剩1分钟
		updateTimeVal, ok := lastUpdateTime.(time.Time)
		if !ok {
			context.AbortWithStatus(http.StatusUnauthorized)
			return
		}
		if now.Sub(updateTimeVal) > time.Second*10 {
			sess.Set("update_time", now)
			_ = sess.Save()
		}
	}
}
